package dao;

import dao.inte.ProductRepository;
import domain.shop.Category;
import domain.shop.Product;

import javax.inject.Singleton;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Singleton
public class ProductRepositoryImpl extends AbstractEntityRepository<Product> implements ProductRepository {
    public ProductRepositoryImpl() {
        super(Product.class);
    }

    @Override
    protected Class<Product> getEntityClass() {
        return Product.class;
    }

    public Product create() throws Exception {
        Product product = new Product();
        return save(product);
    }

    public List<Product> findAllByCategory(Long categoryId) {
        List<Product> result = new ArrayList<Product>();
        for (Product product : this.findAll()) {
            for (Category category : product.getCategories()) {
                if (category.getId().equals(categoryId)) {
                    result.add(product);
                }
            }
        }
        return result;
    }

    public Set<Product> findRelatedProductsByProductId(Long productId) {
        return this.findById(productId).getRelatedProducts();
    }

    public List<Product> findProductsContainingEntryCarType(String carType) {
        Query q = entityManager.createQuery("from Product p where p.carType like :carType");
        carType = "%" + carType + "%";
        q.setParameter("carType", carType);
        return (List<Product>) q.getResultList();
    }

    public List<Product> findProductsByIdLike(Long input) {


        Query query = entityManager.createQuery("SELECT i FROM Product i WHERE  cast(i.id as string)  LIKE :input");
        query.setParameter("input", input + "%");
        return query.getResultList();
    }

    public Iterable<Product> findProducts(int first, int count, String property, boolean ascending) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery cq = cb.createQuery(Product.class);
        Root personEntity = cq.from(Product.class);
        Path attr;
        if (property.equals("id")) {
            attr = personEntity.get("id");
        } else if (property.equals("price")) {
            attr = personEntity.get("price");
        } else {
            attr = personEntity.get("name");
        }
        if (ascending) {
            cq.orderBy(cb.asc(attr));
        } else {
            cq.orderBy(cb.desc(attr));
        }
        TypedQuery<Product> query = entityManager.createQuery(cq);
        query.setFirstResult(first);
        query.setMaxResults(count);
        List<Product> results = query.getResultList();
        return results;
    }
}
